package com.spider.pool;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

/**
 * @author β世界
 * Created on 11:20
 * @Description 核心处理的线程池和持久化处理的线程池
 * 1.这个线程池要做到单方唤醒（即核心线程唤醒持久化线程）
 * 2.当所有的核心处理线程都执行完毕的时候，自动持久化所有的线程
 */
public class ThreadPool {
    private final static Logger logger = LoggerFactory.getLogger(ThreadPool.class);
    /** 线程池 **/
    private final SpiderThreadPoolExecute pool;
    /** 线程计数器 **/
    private volatile CountDownLatch countDownLatch;

    /***
     * @author β世界 on 13:46 2020/3/25
     * @Description 创建线程池
     * @param corePoolSize: 核心线程的数量
     * @param maximumPoolSize: 最大的线程数量
     * @param keepAliveTime: 线程的休息时间
     **/
    public ThreadPool(int corePoolSize,int maximumPoolSize,long keepAliveTime){
        pool = new SpiderThreadPoolExecute(corePoolSize,maximumPoolSize,keepAliveTime,TimeUnit.SECONDS,new LinkedBlockingQueue<>());
    }

    /**
     * @author β世界 on 13:33 2021/3/18
     * 创建线程计数器,这个计数的数量就是需要处理的链接的总数
     * @param count: 计数的总量
     * @return void
     **/
    public void initCountDownLatch(int count){
        countDownLatch = new CountDownLatch(count);
    }

    /**
     * @author β世界 on 11:41 2020/2/14
     * @Description 线程执行
     **/
    public void execute(Runnable runnable){
        // 执行线程
        pool.execute(runnable);
    }

    /**
     * @author β世界 on 13:15 2020/2/14
     * @Description 检查线程池内部是否完全执行完毕的线程是否全部完成
     * @return boolean 
     **/
    public boolean checkExistActive(){
        return pool.getActiveCount() != 0;
    }

    public synchronized void countDown(){
        countDownLatch.countDown(); // 减少线程的计数
    }

    /**
     * @author β世界 on 9:12 2020/9/4
     * 等待线程执行结束,我们设置过这个计数器的上限，如果这个计数器，到了0，那么就会自动唤醒
     **/
    public void await(){
        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * @author β世界 on 17:25 2021/3/17
     * 彻底关闭所有的线程
     * @return void
     **/
    public void shutdown(){
        // 彻底关闭所有的线程
        List<Runnable> runnable = pool.shutdownNow();
        if(runnable.size() != 0){
            logger.warn("爬虫线程池关闭，剩余执行的线程数: "+runnable.size());
        }
    }

    /**
     * @author β世界 on 17:25 2021/3/17
     * 获得程序当前的数值
     * @return java.util.concurrent.CountDownLatch
     **/
    public CountDownLatch getCountDownLatch() {
        return countDownLatch;
    }
}
